package org.qiyu.live.api.service.impl;

import com.alibaba.fastjson2.JSONObject;
import jakarta.annotation.Resource;
import org.apache.dubbo.config.annotation.DubboReference;
import org.idea.qiyu.live.framework.redis.starter.key.GiftProviderCacheKeyBuilder;
import org.qiyu.live.api.service.ILivingRoomService;
import org.qiyu.live.api.vo.LivingRoomInitVO;
import org.qiyu.live.api.vo.req.LivingRoomReqVO;
import org.qiyu.live.api.vo.req.OnlinePkReqVO;
import org.qiyu.live.api.vo.resp.LivingRoomPageResp;
import org.qiyu.live.api.vo.resp.LivingRoomRespVo;
import org.qiyu.live.api.vo.resp.RedPacketReceiveVO;
import org.qiyu.live.common.interfaces.utils.ConvertBeanUtils;
import org.qiyu.live.common.interfaces.vo.PageWrapper;
import org.qiyu.live.im.constants.AppIdEnums;
import org.qiyu.live.im.dto.ImMsgBody;
import org.qiyu.live.msg.enums.ImBiZiCode;
import org.qiyu.live.user.dto.UserDTO;
import org.qiyu.live.user.interfaces.IUserRpc;
import org.qiyu.live.web.starter.context.QiyuRequestContext;
import org.qiyu.live.web.starter.error.ErrorAssert;
import org.qiyu.live.web.starter.error.QiYuBaseError;
import org.qiyu.live.web.starter.error.QiYuBaseErrorEnum;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import qiyu.live.gift.dto.RedPacketConfigReqDTO;
import qiyu.live.gift.dto.RedPacketConfigRespDTO;
import qiyu.live.gift.dto.RedPacketReceiveDTO;
import qiyu.live.gift.dto.SendGiftMq;
import qiyu.live.gift.interfaces.IRedPacketConfigRpc;
import qiyu.live.im.router.interfaces.IMRouterRpc;
import qiyu.live.living.dto.req.LivingRoomReqDTO;
import qiyu.live.living.dto.req.OnlinePkReqDTO;
import qiyu.live.living.dto.resp.LivingRoomRespDTO;
import qiyu.live.living.interfaces.ILivingRoomRpc;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: sfx
 * Date: 2023-10-24
 * Time: 19:46
 */
@Service
public final class LivingRoomServiceImpl implements ILivingRoomService {

    private static final Logger LOGGER = LoggerFactory.getLogger(LivingRoomServiceImpl.class);

    @DubboReference
    private ILivingRoomRpc livingRoomRpc;
    @DubboReference
    private IRedPacketConfigRpc redPacketConfigRpc;

    @DubboReference
    private IUserRpc userRpc;

    @DubboReference
    private IMRouterRpc imRouterRpc;

    @Resource
    private RedisTemplate<String, Object> redisTemplate;
    @Resource
    private GiftProviderCacheKeyBuilder cacheKeyBuilder;

    /**
     * 这里需要远程调用living服务插入
     *
     * @param type 直播间类型
     * @return
     */
    @Override
    public boolean startLivingRoom(Integer type) {
        LivingRoomReqDTO livingRoomReqDTO = new LivingRoomReqDTO();
        Long userId = QiyuRequestContext.getUserId();
        UserDTO userInfo = userRpc.getUserInfo(userId);
        livingRoomReqDTO.setType(type);
        livingRoomReqDTO.setRoomName("主播-" + userId + "的直播间");
        livingRoomReqDTO.setAnchorId(userId);
        livingRoomReqDTO.setCovertImg(userInfo.getAvatar());
        return livingRoomRpc.startLivingRoom(livingRoomReqDTO) > 0;
    }

    /**
     * 这里需要远程调用living服务插入
     *
     * @param roomId 直播间类型
     * @return
     */
    @Override
    public boolean closeLivingRoom(Integer roomId) {
        LivingRoomReqDTO livingRoomReqDTO = new LivingRoomReqDTO();
        livingRoomReqDTO.setRoomId(roomId);
        return livingRoomRpc.closeLivingRoom(livingRoomReqDTO);
    }

    /**
     * @param livingRoomReqVo vo
     * @return 返回直播间列表
     */
    @Override
    public LivingRoomPageResp list(LivingRoomReqVO livingRoomReqVo) {
        PageWrapper<LivingRoomRespDTO> pageWrapper = livingRoomRpc.list(ConvertBeanUtils.convert(livingRoomReqVo, LivingRoomReqDTO.class));
        LivingRoomPageResp livingRoomPageResp = new LivingRoomPageResp();
        livingRoomPageResp.setList(ConvertBeanUtils.convertList(pageWrapper.getList(), LivingRoomRespVo.class));
        livingRoomPageResp.setHasNext(pageWrapper.isHasNext());
        return livingRoomPageResp;
    }

    /**
     * 记录pk的一方
     *
     * @param onlinePkReqVO
     * @return
     */
    @Override
    public boolean onlinePk(OnlinePkReqVO onlinePkReqVO) {
        boolean isSuccess = livingRoomRpc.onlinePk(ConvertBeanUtils.convert(onlinePkReqVO, OnlinePkReqDTO.class));
        ErrorAssert.isNotBlank(isSuccess, QiYuBaseErrorEnum.LIVING_PK_BUSY);
        return true;
    }

    @Override
    public LivingRoomInitVO anchorConfig(Long userId, Integer roomId) {
        LivingRoomRespDTO respDTO = livingRoomRpc.queryByRoomId(roomId);
        ErrorAssert.isNotNull(respDTO, QiYuBaseErrorEnum.PARAM_ERROR);
        Map<Long, UserDTO> userDTOMap = userRpc.batchQueryUserInfo(Arrays.asList(respDTO.getAnchorId(), userId)
                .stream().distinct().collect(Collectors.toList()));
        UserDTO anchor = userDTOMap.get(respDTO.getAnchorId());
        UserDTO watcher = userDTOMap.get(userId);
        LivingRoomInitVO respVO = new LivingRoomInitVO();
        respVO.setAnchorNickName(anchor.getNickName());
        respVO.setWatcherNickName(watcher.getNickName());
        respVO.setUserId(userId);
        //给定一个默认的头像
        respVO.setAvatar(StringUtils.isEmpty(anchor.getAvatar()) ?
                "https://s1.ax1x.com/2022/12/18/zb6q6f.png" : anchor.getAvatar());
        respVO.setWatcherAvatar(watcher.getAvatar());
        if (respDTO == null || respDTO.getAnchorId() == null || userId == null) {
            //这种就是属于直播间已经不存在的情况了
            respVO.setRoomId(-1);
        } else {
            respVO.setRoomId(respDTO.getId());
            respVO.setAnchorId(respDTO.getAnchorId());
            respVO.setAnchor(respDTO.getAnchorId().equals(userId));
            // 还需要当前主播有没有红包雨的配置
            RedPacketConfigRespDTO redPacketConfigRespDTO = redPacketConfigRpc.queryRedPacketConfigByAnchorId(Math.toIntExact(respDTO.getAnchorId()));
            // 设置红包雨对应的唯一标识
            respVO.setConfigCode(redPacketConfigRespDTO.getConfigCode());
        }
        respVO.setDefaultBgImg("https://picst.sunbangyan.cn/2023/08/29/waxzj0.png");
        return respVO;
    }

    @Override
    public Boolean prepareRedPacket(Integer roomId, Long anchorId) {
        // 校验参数,直播间是否存在
        LivingRoomRespDTO livingRoomRespDTO = livingRoomRpc.queryByRoomId(roomId);
        ErrorAssert.isNotNull(livingRoomRespDTO, QiYuBaseErrorEnum.PARAM_ERROR);
        // 2. 当前房间的主播id是否和当前的主播对的上
        ErrorAssert.isNotBlank(livingRoomRespDTO.getAnchorId().equals(anchorId), QiYuBaseErrorEnum.PARAM_ERROR);
        return redPacketConfigRpc.prepareRedPacket(Math.toIntExact(anchorId));
    }


    @Override
    public RedPacketReceiveVO getRedPacket(Long userId, String redPacketConfigCode) {
        RedPacketConfigReqDTO redPacketConfigReqDTO = new RedPacketConfigReqDTO();
        redPacketConfigReqDTO.setConfigCode(redPacketConfigCode);
        redPacketConfigReqDTO.setUserId(userId);
        RedPacketReceiveDTO redPacketReceiveDTO = redPacketConfigRpc.redPacketReceive(redPacketConfigReqDTO);
        RedPacketReceiveVO redPacketReceiveVO = new RedPacketReceiveVO();
        if (redPacketReceiveDTO == null) {
            redPacketReceiveVO.setMsg("红包已经领取完毕");
        } else {
            redPacketReceiveVO.setPrice(redPacketReceiveDTO.getPrice());
        }
        return redPacketReceiveVO;
    }

    @Override
    public Boolean startRedPacket(Long userId, String redPacketConfigCode) {
        // 1. 保证红包雨数据已经初始化完成
        String prepareCacheKey = cacheKeyBuilder.buildRedPacketPrepareSuccessCacheKey(redPacketConfigCode);
        if (!redisTemplate.hasKey(prepareCacheKey)) {
            // 红包雨还没有初始化完成
            return false;
        }
        // 2. 防重复-->我们规定红包雨只能发送一次(在一场直播中)
        String startCacheKey = cacheKeyBuilder.buildRedPacketStartSuccessCacheKey(redPacketConfigCode);
        if (!redisTemplate.hasKey(startCacheKey)) {
            // 红包雨还没有初始化完成
            return false;
        }
        // 3. 进行广播发送红包雨-->发送带有START_RED_PACKET的消息->广播发送
        // 3.1 根据主播id查询roomId

        sendImMsgBatch(1,ImBiZiCode.START_RED_PACKET.getCode(), new JSONObject());

        return null;
    }

    private void sendImMsgBatch(Integer roomId, int bizCode, JSONObject jsonObject) {
        // 批量的查询直播间的所有在线用户,构建好imMsgBodies
        LivingRoomReqDTO livingRoomReqDTO = new LivingRoomReqDTO();
        livingRoomReqDTO.setRoomId(roomId);
        List<Long> userIdList = livingRoomRpc.queryUserIdsByRoomId(livingRoomReqDTO);
        List<ImMsgBody> imMsgBodies = userIdList.stream().map(userId -> {
            ImMsgBody imMsgBody = new ImMsgBody();
            imMsgBody.setAppId(AppIdEnums.QIYU_LIVE_BIZ.getCode());
            imMsgBody.setRoomId(roomId);
            imMsgBody.setBiZiCode(bizCode);
            imMsgBody.setUserId(userId);
            imMsgBody.setData(jsonObject.toString());
            return imMsgBody;
        }).collect(Collectors.toList());
        imRouterRpc.batchSendMsg(imMsgBodies);
    }
}